home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / GC / gc.h < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-25  |  22.1 KB  |  676 lines

  1. /* Copyright 1988,1989 Hans-J. Boehm, Alan J. Demers                       */
  2. /* Machine specific parts contributed by various people.  See README file. */
  3.  
  4. /*********************************/
  5. /*                               */
  6. /* Definitions for conservative  */
  7. /* collector                     */
  8. /*                               */
  9. /*********************************/
  10.  
  11. /*********************************/
  12. /*                               */
  13. /* Easily changeable parameters  */
  14. /*                               */
  15. /*********************************/
  16.  
  17. # if defined(sun) && defined(mc68000)
  18. #    define M68K_SUN
  19. #    define mach_type_known
  20. # endif
  21. # if defined(hp9000s300)
  22. #    define M68K_HP
  23. #    define mach_type_known
  24. # endif
  25. # if defined(vax)
  26. #    define VAX
  27. #    define mach_type_known
  28. # endif
  29. # if defined(mips)
  30. #    define MIPS
  31. #    define mach_type_known
  32. # endif
  33. # if defined(sequent) && defined(i386)
  34. #    define I386
  35. #    define mach_type_known
  36. # endif
  37. # if defined(ibm032)
  38. #   define RT
  39. #   define mach_type_known
  40. # endif
  41. # if defined(sun) && defined(sparc)
  42. #   define SPARC
  43. #   define mach_type_known
  44. # endif
  45.  
  46.  
  47. /* Feel free to add more clauses here */
  48.  
  49. /* Or manually define the machine type here: */
  50. # ifndef mach_type_known
  51. #   define M68K_SUN /* Guess "Sun" */
  52.             /* Mapping is: M68K_SUN   ==> Sun3,                */
  53.             /*             M68K_HP    ==> HP9000/300,          */
  54.             /*             I386       ==> Sequent Symmetry,    */
  55.                     /*             NS32K      ==> Encore Multimax,     */
  56.                     /*             MIPS       ==> R2000 or R3000       */
  57. # endif
  58.  
  59. #define PRINTSTATS  /* Print garbage collection statistics                  */
  60.             /* For less verbose output, undefine in reclaim.c      */
  61.  
  62. #define PRINTTIMES  /* Print the amount of time consumed by each garbage   */
  63.             /* collection.                                         */
  64.  
  65. #define PRINTBLOCKS /* Print object sizes associated with heap blocks,     */
  66.             /* whether the objects are atomic or composite, and    */
  67.             /* whether or not the block was found to be empty      */
  68.             /* duing the reclaim phase.  Typically generates       */
  69.             /* about one screenful per garbage collection.         */
  70. #undef PRINTBLOCKS
  71.  
  72. #ifdef SILENT
  73. #  ifdef PRINTSTATS
  74. #    undef PRINTSTATS
  75. #  endif
  76. #  ifdef PRINTTIMES
  77. #    undef PRINTTIMES
  78. #  endif
  79. #  ifdef PRINTNBLOCKS
  80. #    undef PRINTNBLOCKS
  81. #  endif
  82. #endif
  83.  
  84. #define HBLK_MAP    /* Maintain a map of all potential heap blocks        */
  85.             /* starting at heapstart.                             */
  86.             /* Normally, this performs about as well as the       */
  87.             /* standard stack of chunk pointers that is used      */
  88.             /* otherwise.  It loses if a small section of the     */
  89.             /* heap consists of garbage collected objects.        */
  90.             /* It is ESSENTIAL if pointers to object interiors    */
  91.             /* are considered valid, i.e. if INTERIOR_POINTERS    */
  92.             /* is defined.                                        */
  93. #undef HBLK_MAP
  94.  
  95. #define MAP_SIZE 8192  /* total data size < MAP_SIZE * HBLKSIZE = 32 Meg  */
  96. #define MAXHBLKS 4096  /* Maximum number of chunks which can be           */
  97.                /* allocated                                       */
  98. #define INTERIOR_POINTERS
  99.             /* Follow pointers to the interior of an object.      */
  100.             /* Substantially increases the probability of         */
  101.             /* unnnecessary space retention.  May be necessary    */
  102.             /* with gcc -O or other C compilers that may clobber  */
  103.             /* values of dead variables prematurely.  Pcc         */
  104.             /* derived compilers appear to pose no such problems. */
  105.             /* Empirical evidence suggests that this is probably  */
  106.             /* still OK for most purposes, so long as pointers    */
  107.             /* are known to be 32 bit aligned.  The combination   */
  108.             /* of INTERIOR_POINTERS and UNALIGNED (e.g. on a      */
  109.             /* Sun 3 with the standard compiler) causes easily    */
  110.             /* observable spurious retention and performance      */
  111.             /* degradation.                                       */
  112. #undef INTERIOR_POINTERS
  113.  
  114. #ifdef SPARC
  115. #   define ALIGN_DOUBLE  /* Align objects of size > 1 word on 2 word   */
  116.              /* boundaries.  Wasteful of memory, but       */
  117.              /* apparently required by SPARC architecture. */
  118.  
  119. #endif
  120.  
  121. #if defined(INTERIOR_POINTERS) && !defined(HBLK_MAP)
  122.     --> check for interior pointers requires a heap block map
  123. #endif
  124.  
  125. #define MERGE_SIZES /* Round up some object sizes, so that fewer distinct */
  126.             /* free lists are actually maintained.  This applies  */
  127.             /* only to the top level routines in misc.c, not to   */
  128.             /* user generated code that calls allocobj and        */
  129.             /* allocaobj directly.                                */
  130.             /* Slows down average programs slightly.  May however */
  131.             /* substantially reduce fragmentation if allocation   */
  132.             /* request sizes are widely scattered.                */
  133. #undef MERGE_SIZES
  134.  
  135. /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
  136. # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
  137. #   define MERGE_SIZES
  138. # endif
  139.  
  140.  
  141. /* For PRINTTIMES to tell the truth, we need to know the value of HZ for
  142.    this system. */
  143.  
  144. #if defined(M68K_HP) || defined(M68K_SUN) || defined(SPARC)
  145. #  include <sys/param.h>
  146. #  define FLOAT_HZ (double)HZ
  147. #else
  148. #  define FLOAT_HZ 60.0    /* Guess that we're in the U.S. */
  149. #endif
  150.  
  151. #ifdef M68K_SUN
  152. #  define UNALIGNED       /* Pointers are not longword aligned         */
  153. #  define ALIGNMENT   2   /* Pointers are aligned on 2 byte boundaries */
  154.               /* by the Sun C compiler.                    */
  155. #else
  156. #  ifdef VAX
  157. #    undef UNALIGNED      /* Pointers are longword aligned by 4.2 C compiler */
  158. #    define ALIGNMENT 4
  159. #  else
  160. #    ifdef RT
  161. #      undef UNALIGNED
  162. #      define ALIGNMENT 4
  163. #    else
  164. #      ifdef SPARC
  165. #        undef UNALIGNED
  166. #        define ALIGNMENT 4
  167. #      else
  168. #        ifdef I386
  169. #           undef UNALIGNED         /* Sequent compiler aligns pointers */
  170. #           define ALIGNMENT 4
  171. #        else
  172. #          ifdef NS32K
  173. #            undef UNALIGNED        /* Pointers are aligned on NS32K */
  174. #            define ALIGNMENT 4
  175. #          else
  176. #            ifdef MIPS
  177. #              undef UNALIGNED      /* MIPS hardware requires pointer */
  178.                     /* alignment                      */
  179. #              define ALIGNMENT 4
  180. #            else
  181. #              ifdef M68K_HP
  182. #                define UNALIGNED
  183. #                define ALIGNMENT 2 /* 2 byte alignment inside struct/union, */
  184.                     /* 4 bytes elsewhere */
  185. #              else
  186.          --> specify alignment <--
  187. #              endif
  188. #            endif
  189. #          endif
  190. #        endif
  191. #      endif
  192. #    endif
  193. #  endif
  194. # endif
  195.  
  196. # ifdef RT
  197. #   define STACKTOP ((word *) 0x1fffd800)
  198. # else
  199. #   ifdef I386
  200. #     define STACKTOP ((word *) 0x3ffff000)  /* For Sequent */
  201. #   else
  202. #     ifdef NS32K
  203. #       define STACKTOP ((word *) 0xfffff000) /* for Encore */
  204. #     else
  205. #       ifdef MIPS
  206. #         define STACKTOP ((word *) 0x7ffff000)
  207.                   /* Could probably be slightly lower since  */
  208.                   /* startup code allocates lots of junk     */
  209. #       else
  210. #         ifdef M68K_HP
  211. #           define STACKTOP ((word *) 0xffeffffc)
  212.                   /* empirically determined.  seems to work. */
  213. #         else
  214.         /* VAX, SPARC, and various flavors of Sun 2s and Sun 3s use the */
  215.         /* default heuristic, which is to take the address of a local   */
  216.         /* variable in gc_init, and round it up to the next multiple    */
  217.         /* of 16 Meg.  This is crucial on Suns, since various models    */
  218.         /* that are supposed to be able to share executables, do not    */
  219.         /* use the same stack base.  In particular, Sun 3/80s are       */
  220.         /* different from other Sun 3s.                                 */
  221.         /* This probably works on some more of the above machines.      */
  222. #         endif
  223. #       endif
  224. #     endif
  225. #   endif
  226. # endif
  227.  
  228. /* Start of data segment for each of the above systems.  Note that the */
  229. /* default case works only for contiguous text and data, such as on a  */
  230. /* Vax.                                                                */
  231. # ifdef M68K_SUN
  232. #   define DATASTART ((char *)((((long) (&etext)) + 0x1ffff) & ~0x1ffff))
  233. # else
  234. #   ifdef RT
  235. #     define DATASTART ((char *) 0x10000000)
  236. #   else
  237. #     ifdef I386
  238. #       define DATASTART ((char *)((((long) (&etext)) + 0xfff) & ~0xfff))
  239. #     else
  240. #       ifdef NS32K
  241.       extern char **environ;
  242. #         define DATASTART ((char *)(&environ))
  243.                   /* hideous kludge: environ is the first   */
  244.                   /* word in crt0.o, and delimits the start */
  245.                   /* of the data segment, no matter which   */
  246.                   /* ld options were passed through.        */
  247. #       else
  248. #         ifdef MIPS
  249. #           define DATASTART 0x10000000
  250.                   /* Could probably be slightly higher since */
  251.                   /* startup code allocates lots of junk     */
  252. #         else
  253. #           ifdef M68K_HP
  254. #             define DATASTART ((char *)((((long) (&etext)) + 0xfff) & ~0xfff))
  255. #           else
  256. #             define DATASTART (&etext)
  257. #           endif
  258. #         endif
  259. #       endif
  260. #     endif
  261. #   endif
  262. # endif
  263.  
  264. # define HINCR 16          /* Initial heap increment, in blocks of 4K        */
  265. # define MAXHINCR 512      /* Maximum heap increment, in blocks              */
  266. # define HINCR_MULT 3      /* After each new allocation, hincr is multiplied */
  267. # define HINCR_DIV 2       /* by HINCR_MULT/HINCR_DIV                        */
  268. # define GC_MULT 3         /* Don't collect if the fraction of   */
  269.                /* non-collectable memory in the heap */
  270.                /* exceeds GC_MUL/GC_DIV              */
  271. # define GC_DIV  4
  272.  
  273. # define NON_GC_HINCR 8    /* Heap increment if most of heap if collection */
  274.                /* was suppressed because most of heap is not   */
  275.                /* collectable                                  */
  276.  
  277. /*  heap address bounds.  These are extreme bounds used for sanity checks. */
  278. /*  HEAPLIM may have to be increased for machines with incredibly large    */
  279. /*  amounts of memory.                                                     */
  280.  
  281. #ifdef RT
  282. #   define HEAPSTART 0x10000000
  283. #   define HEAPLIM   0x1fff0000
  284. #else
  285. # if defined(M68K_SUN) || defined(M68K_HP)
  286. #   define HEAPSTART 0x00010000
  287. #   define HEAPLIM   0x04000000
  288. # else
  289. #   ifdef SPARC
  290. #       define HEAPSTART 0x00010000
  291. #       define HEAPLIM   0x10000000
  292. #   else
  293. #     ifdef VAX
  294. #       define HEAPSTART 0x400
  295. #       define HEAPLIM   0x10000000
  296. #     else
  297. #       ifdef I386
  298. #         define HEAPSTART 0x1000
  299. #         define HEAPLIM 0x10000000
  300. #       else
  301. #         ifdef NS32K
  302. #           define HEAPSTART 0x2000
  303. #           define HEAPLIM   0x10000000
  304. #         else
  305. #           ifdef MIPS
  306. #             define HEAPSTART 0x10000000
  307. #             define HEAPLIM 0x20000000
  308. #           else
  309.            --> values unknown <--
  310. #           endif
  311. #         endif
  312. #       endif
  313. #     endif
  314. #   endif
  315. # endif
  316. #endif
  317.  
  318. /*********************************/
  319. /*                               */
  320. /* Machine-dependent defines     */
  321. /*                               */
  322. /*********************************/
  323.  
  324. #define WORDS_TO_BYTES(x)   ((x)<<2)
  325. #define BYTES_TO_WORDS(x)   ((x)>>2)
  326.  
  327. #define WORDSZ              32
  328. #define LOGWL               5    /* log[2] of above */
  329. #define BYTES_PER_WORD      (sizeof (word))
  330. #define ONES                0xffffffff
  331. #define MSBYTE              0xff000000
  332. #define SIGNB               0x80000000
  333. #define MAXSHORT            0x7fff
  334. #define modHALFWORDSZ(n) ((n) & 0xf)    /* mod n by size of half word    */
  335. #define divHALFWORDSZ(n) ((n) >> 4)    /* divide n by size of half word */
  336. #define modWORDSZ(n) ((n) & 0x1f)       /* mod n by size of word         */
  337. #define divWORDSZ(n) ((n) >> 5)         /* divide n by size of word      */
  338. #define twice(n) ((n) << 1)             /* double n                      */
  339.  
  340. typedef unsigned long word;
  341.  
  342. #define TRUE  1
  343. #define FALSE 0
  344.  
  345. /*********************/
  346. /*                   */
  347. /*  Size Parameters  */
  348. /*                   */
  349. /*********************/
  350.  
  351. /*  heap block size, bytes */
  352. /* for RT see comment below */
  353.  
  354. #define HBLKSIZE   0x1000
  355.  
  356.  
  357. /*  max size objects supported by freelist (larger objects may be   */
  358. /*  allocated, but less efficiently)                                */
  359. /*      asm(".set MAXOBJSZ,0x200")      if HBLKSIZE/2 == 0x200      */
  360.  
  361. #define MAXOBJSZ    (HBLKSIZE/8)
  362.         /* Should be BYTES_TO_WORDS(HBLKSIZE/2), but a cpp */
  363.         /* misfeature prevents that.                       */
  364. #define MAXAOBJSZ   (HBLKSIZE/8)
  365.  
  366. # define divHBLKSZ(n) ((n) >> 12)
  367.  
  368. # define modHBLKSZ(n) ((n) & 0xfff)
  369.  
  370. # define HBLKPTR(objptr) ((struct hblk *)(((long) (objptr)) & ~0xfff))
  371.  
  372.  
  373.  
  374. /********************************************/
  375. /*                                          */
  376. /*    H e a p   B l o c k s                 */
  377. /*                                          */
  378. /********************************************/
  379.  
  380. /*  heap block header */
  381. #define HBLKMASK   (HBLKSIZE-1)
  382.  
  383. #define BITS_PER_HBLK (HBLKSIZE * 8)
  384.  
  385. #define MARK_BITS_PER_HBLK (BITS_PER_HBLK/WORDSZ)
  386.        /* upper bound                                    */
  387.        /* We allocate 1 bit/word.  Only the first word   */
  388.        /* in each object is actually marked.             */
  389.  
  390. # ifdef ALIGN_DOUBLE
  391. #   define MARK_BITS_SZ (((MARK_BITS_PER_HBLK + 2*WORDSZ - 1)/(2*WORDSZ))*2)
  392. # else
  393. #   define MARK_BITS_SZ ((MARK_BITS_PER_HBLK + WORDSZ - 1)/WORDSZ)
  394. # endif
  395.        /* Upper bound on number of mark words per heap block  */
  396.  
  397. struct hblkhdr {
  398.     long hbh_sz;    /* sz > 0 ==> objects are sz-tuples of poss. pointers */
  399.             /* sz < 0 ==> objects are sz-tuples not pointers      */
  400.             /* if free, the size in bytes of the whole block      */
  401.             /* Misc.c knows that hbh_sz comes first.              */
  402. # ifndef HBLK_MAP
  403.     struct hblk ** hbh_index;   /* Pointer to heap block list entry   */
  404.                 /* for this block                     */
  405. # else
  406. #   ifdef ALIGN_DOUBLE
  407.       /* Add another 1 word field to make the total even.  Gross, but ... */
  408.     long hbh_dummy;
  409. #   endif
  410. # endif
  411.     struct hblk * hbh_next; /* Link field for hblk free list */
  412.     long hbh_mask;      /* If hbh_mask >= 0 then:                          */
  413.             /*   x % (4 * hbh_sz) == x & hbh_mask              */
  414.             /*   sz is a power of 2 and < the size of a heap   */
  415.             /*     block.                                      */
  416.             /* A hack to speed up pointer validity check on    */
  417.             /* machines with slow division.                    */
  418.     long hbh_marks[MARK_BITS_SZ];
  419.                 /* Bit i in the array refers to the             */
  420.                 /* object starting at the ith word (header      */
  421.                 /* INCLUDED) in the heap block.                 */
  422.                 /* For free blocks, hbh_marks[0] = 1, indicates */
  423.                 /* block is uninitialized.                      */
  424. };
  425.  
  426. /*  heap block body */
  427.  
  428. # define BODY_SZ ((HBLKSIZE-sizeof(struct hblkhdr))/sizeof(word))
  429.  
  430. struct hblk {
  431.     struct hblkhdr hb_hdr;
  432.     word hb_body[BODY_SZ];
  433. };
  434.  
  435. # define hb_sz hb_hdr.hbh_sz
  436. # ifndef HBLK_MAP
  437. #   define hb_index hb_hdr.hbh_index
  438. # endif
  439. # define hb_marks hb_hdr.hbh_marks
  440. # define hb_next hb_hdr.hbh_next
  441. # define hb_uninit hb_hdr.hbh_marks[0]
  442. # define hb_mask hb_hdr.hbh_mask
  443.  
  444. /*  lists of all heap blocks and free lists  */
  445. /* These are grouped together in a struct    */
  446. /* so that they can be easily skipped by the */
  447. /* mark routine.                             */
  448. /* Mach_dep.c knows about the internals      */
  449. /* of this structure.                        */
  450.  
  451. struct __gc_arrays {
  452.   struct obj * _aobjfreelist[MAXAOBJSZ+1];
  453.               /* free list for atomic objs*/
  454.   struct obj * _objfreelist[MAXOBJSZ+1];
  455.               /* free list for objects */
  456. # ifdef HBLK_MAP
  457.     char _hblkmap[MAP_SIZE];
  458. #   define HBLK_INVALID 0    /* Not administered by collector   */
  459. #   define HBLK_VALID 0x7f   /* Beginning of a valid heap block */
  460.     /* A value n, 0 < n < 0x7f denotes the continuation of a valid heap    */
  461.     /* block which starts at the current address - n * HBLKSIZE or earlier */
  462. # else
  463.     struct hblk * _hblklist[MAXHBLKS];
  464. # endif
  465. };
  466.  
  467. extern struct __gc_arrays _gc_arrays; 
  468.  
  469. # define objfreelist _gc_arrays._objfreelist
  470. # define aobjfreelist _gc_arrays._aobjfreelist
  471. # ifdef HBLK_MAP
  472. #   define hblkmap _gc_arrays._hblkmap
  473. # else
  474. #   define hblklist _gc_arrays._hblklist
  475. # endif
  476.  
  477. # define begin_gc_arrays ((char *)(&_gc_arrays))
  478. # define end_gc_arrays (((char *)(&_gc_arrays)) + (sizeof _gc_arrays))
  479.  
  480. struct hblk ** last_hblk;  /* Pointer to one past the real end of hblklist */
  481.  
  482. struct hblk * hblkfreelist;
  483.  
  484. extern long heapsize;       /* Heap size in bytes */
  485.  
  486. long hincr;                /* current heap increment, in blocks              */
  487.  
  488. /* Operations */
  489. # define update_hincr  hincr = (hincr * HINCR_MULT)/HINCR_DIV; \
  490.                if (hincr > MAXHINCR) {hincr = MAXHINCR;}
  491. # define HB_SIZE(p) abs((p) -> hb_sz)
  492. # define abs(x)  ((x) < 0? (-(x)) : (x))
  493.  
  494. /*  procedures */
  495.  
  496. extern void
  497. freehblk();
  498.  
  499. extern struct hblk *
  500. allochblk();
  501.  
  502. /****************************/
  503. /*                          */
  504. /*   Objects                */
  505. /*                          */
  506. /****************************/
  507.  
  508. /*  object structure */
  509.  
  510. struct obj {
  511.     union {
  512.     struct obj *oun_link;   /* --> next object in freelist */
  513. #         define obj_link       obj_un.oun_link
  514.     word oun_component[1];  /* treats obj as list of words */
  515. #         define obj_component  obj_un.oun_component
  516.     } obj_un;
  517. };
  518.  
  519. /*  Test whether something points to a legitimate heap object */
  520.  
  521.  
  522. extern char end;
  523.  
  524. # ifdef HBLK_MAP
  525.   char * heapstart; /* A lower bound on all heap addresses */
  526.             /* Known to be HBLKSIZE aligned.       */
  527. # endif
  528.  
  529. char * heaplim;   /* 1 + last address in heap */
  530.  
  531. word * stacktop;  /* 1 + highest address in stack.  Set by gc_init. */
  532.  
  533. /* Check whether the given HBLKSIZE aligned hblk pointer refers to the   */
  534. /* beginning of a legitimate chunk.                                      */
  535. /* Assumes that *p is addressable                                        */
  536. # ifdef HBLK_MAP
  537. #   define is_hblk(p)  (hblkmap[divHBLKSZ(((long)p) - ((long)heapstart))] \
  538.             == HBLK_VALID)
  539. # else
  540. #   define is_hblk(p) ( (p) -> hb_index >= hblklist \
  541.             && (p) -> hb_index < last_hblk \
  542.             && *((p)->hb_index) == (p))
  543. # endif
  544. # ifdef INTERIOR_POINTERS
  545.     /* Return the hblk_map entry for the pointer p */
  546. #     define get_map(p)  (hblkmap[divHBLKSZ(((long)p) - ((long)heapstart))])
  547. # endif
  548.  
  549. # ifdef INTERIOR_POINTERS
  550.   /* Return the word displacement of the beginning of the object to       */
  551.   /* which q points.  q is an address inside hblk p for objects of size s */
  552.   /* with mask m corresponding to s.                                      */
  553. #  define get_word_no(q,p,s,m) \
  554.         (((long)(m)) >= 0 ? \
  555.         (((((long)q) - ((long)p) - (sizeof (struct hblkhdr))) & ~(m)) \
  556.          + (sizeof (struct hblkhdr)) >> 2) \
  557.         : ((((long)q) - ((long)p) - (sizeof (struct hblkhdr)) >> 2) \
  558.            / (s)) * (s) \
  559.            + ((sizeof (struct hblkhdr)) >> 2))
  560. # else
  561.   /* Check whether q points to an object inside hblk p for objects of size s */
  562.   /* with mask m corresponding to s.                                         */
  563. #  define is_proper_obj(q,p,s,m) \
  564.         (((long)(m)) >= 0 ? \
  565.         (((((long)(q)) - (sizeof (struct hblkhdr))) & (m)) == 0) \
  566.         : (((long) (q)) - ((long)(p)) - (sizeof (struct hblkhdr))) \
  567.            % ((s) << 2) == 0)
  568. #  endif
  569.  
  570. /* The following is a quick test whether something is an object pointer */
  571. /* It may err in the direction of identifying bogus pointers            */
  572. /* Assumes heap + text + data + bss < 64 Meg.                           */
  573. #ifdef M68K_SUN
  574. #   define TMP_POINTER_MASK 0xfc000003  /* pointer & POINTER_MASK should be 0 */
  575. #else
  576. # ifdef RT
  577. #   define TMP_POINTER_MASK 0xc0000003
  578. # else
  579. #   ifdef VAX
  580. #     define TMP_POINTER_MASK 0xfc000003
  581. #   else
  582. #     ifdef SPARC
  583. #       define TMP_POINTER_MASK 0xfc000003
  584. #     else
  585. #       ifdef I386
  586. #         define TMP_POINTER_MASK 0xfc000003
  587. #       else
  588. #         ifdef NS32K
  589. #           define TMP_POINTER_MASK 0xfc000003
  590. #         else
  591. #           ifdef MIPS
  592. #             define TMP_POINTER_MASK 0xc0000003
  593. #           else
  594. #             ifdef M68K_HP
  595. #               define TMP_POINTER_MASK 0xfc000003
  596. #             else
  597.           --> dont know <--
  598. #             endif
  599. #           endif
  600. #         endif
  601. #       endif
  602. #     endif
  603. #   endif
  604. # endif
  605. #endif
  606.  
  607. #ifdef INTERIOR_POINTERS
  608. #   define POINTER_MASK (TMP_POINTER_MASK & 0xfffffff8)
  609.     /* Don't pay attention to whether address is properly aligned */
  610. #else
  611. #   define POINTER_MASK TMP_POINTER_MASK
  612. #endif
  613.  
  614. #ifdef HBLK_MAP
  615. #  define quicktest(p) (((long)(p)) > ((long)(heapstart)) \
  616.             && !(((unsigned long)(p)) & POINTER_MASK))
  617. #else
  618. # ifdef UNALIGNED
  619. #  define quicktest(p) (((long)(p)) > ((long)(&end)) \
  620.                         && !(((unsigned long)(p)) & POINTER_MASK) \
  621.                         && (((long)(p)) & HBLKMASK))
  622.     /* The last test throws out pointers to the beginning of heap */
  623.         /* blocks.  Small integers shifted by 16 bits tend to look    */
  624.         /* like these.                                                */
  625. # else
  626. #  define quicktest(p) (((long)(p)) > ((long)(&end)) \
  627.             && !(((unsigned long)(p)) & POINTER_MASK))
  628. # endif
  629. #endif
  630.  
  631.  
  632. /*  Marks are in a reserved area in                          */
  633. /*  each heap block.  Each word has one mark bits associated */
  634. /*  with it. Only those corresponding to the beginning of an */
  635. /*  object are used.                                         */
  636.  
  637.  
  638. /* Operations */
  639.  
  640. /*
  641.  * Retrieve, set, clear the mark bit corresponding
  642.  * to the nth word in a given heap block.
  643.  * Note that retrieval will work, so long as *hblk is addressable.
  644.  * In particular, the check whether hblk is a legitimate heap block
  645.  * can be postponed until after the mark bit is examined.
  646.  *
  647.  * (Recall that bit n corresponds to object beginning at word n)
  648.  */
  649.  
  650. # define mark_bit(hblk,n) (((hblk)->hb_marks[divWORDSZ(n)] \
  651.                 >> (modWORDSZ(n))) & 1)
  652.  
  653. /* The following assume the mark bit in question is either initially */
  654. /* cleared or it already has its final value                         */
  655. # define set_mark_bit(hblk,n) (hblk)->hb_marks[divWORDSZ(n)] \
  656.                 |= 1 << modWORDSZ(n)
  657.  
  658. # define clear_mark_bit(hblk,n) (hblk)->hb_marks[divWORDSZ(n)] \
  659.                 &= ~(1 << modWORDSZ(n))
  660.  
  661. /*  procedures */
  662.  
  663. /* Small object allocation routines */
  664. extern struct obj * allocobj();
  665. extern struct obj * allocaobj();
  666.  
  667. /* Small object allocation routines that mark only from registers */
  668. /* expected to be preserved by C.                                 */
  669. extern struct obj * _allocobj();
  670. extern struct obj * _allocaobj();
  671.  
  672. /* general purpose allocation routines */
  673. extern struct obj * gc_malloc();
  674. extern struct obj * gc_malloc_atomic();
  675.  
  676.